package game.poker.holdem.card;

import java.util.HashMap;
import java.util.Map;

public class Card implements Comparable<Card> {
	private static final Map<Suit, Map<Rank, Card>> cardCacheMap;
	
	static {
		cardCacheMap = new HashMap<Suit, Map<Rank, Card>>();
	}
	
	private final Suit suit;
	private final Rank rank;
	
	private Card(Suit suit, Rank rank) {
		this.suit = suit;
		this.rank = rank;
	}
	
	public static Card valueOf(Suit suit, Rank rank) {
		Map<Rank, Card> rankCardMap = cardCacheMap.get(suit);
		if(rankCardMap == null) {
			rankCardMap = new HashMap<Rank, Card>();
			cardCacheMap.put(suit, rankCardMap);			
		}
		Card card = rankCardMap.get(rank);
		if(card == null) {
			card = new Card(suit, rank);
			rankCardMap.put(rank, card);
		}
		return card;
	}

	public Suit getSuit() {
		return suit;
	}

	public Rank getRank() {
		return rank;
	}
	
	
	
	@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((rank == null) ? 0 : rank.hashCode());
        result = prime * result + ((suit == null) ? 0 : suit.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Card other = (Card) obj;
        if (rank != other.rank)
            return false;
        if (suit != other.suit)
            return false;
        return true;
    }

    @Override
	public String toString() {
		return "Card [suit=" + suit + ", rank=" + rank + "]";
	}

	@Override
	public int compareTo(Card c) {		
		return suit != c.suit ? suit.compareTo(c.suit) : rank.compareTo(c.rank);
	}	
}
